
package org.xteam.box2text.parser.ast;

public class BoxAstPrinter extends DefaultBoxVisitor {

	private java.io.PrintStream out;
	private int indentLevel;
	
	public BoxAstPrinter(java.io.PrintStream out) {
		this.out = out;
		indentLevel = 0;
	}
	
	public void visitBoxFile(BoxFile aBoxFile) {
		out.print("BoxFile(");
		++indentLevel;out.println();
		printIndent();
		out.print("importName=");
		if (aBoxFile.getImportName() != null) {
			aBoxFile.getImportName().visit(this);
		} else {
			out.println("null");
		}
		printIndent();
		out.print("rules=");
		if (aBoxFile.getRules() != null) {
			out.println("[");
			++indentLevel;
			for (Rule e : aBoxFile.getRules()) {
				printIndent();
				e.visit(this);
			}
			--indentLevel;
			printIndent();
			out.println("]");
		} else {
			out.println("null");
		}
		--indentLevel;printIndent();
		out.println(")");
	}
	
	public void visitRule(Rule aRule) {
		out.print("Rule(");
		++indentLevel;out.println();
		printIndent();
		out.print("className=");
		if (aRule.getClassName() != null) {
			aRule.getClassName().visit(this);
		} else {
			out.println("null");
		}
		printIndent();
		out.print("boxspec=");
		if (aRule.getBoxspec() != null) {
			aRule.getBoxspec().visit(this);
		} else {
			out.println("null");
		}
		--indentLevel;printIndent();
		out.println(")");
	}
	
	public void visitTextBox(TextBox aTextBox) {
		out.print("TextBox(");
		out.print("contents=");
		if (aTextBox.getContents() != null) {
			out.print(aTextBox.getContents());
		} else {
			out.print("null");
		}
		out.println(")");
	}
	
	public void visitModelAccess(ModelAccess aModelAccess) {
		out.print("ModelAccess(");
		++indentLevel;out.println();
		printIndent();
		out.print("expr=");
		if (aModelAccess.getExpr() != null) {
			aModelAccess.getExpr().visit(this);
		} else {
			out.println("null");
		}
		printIndent();
		out.print("options=");
		if (aModelAccess.getOptions() != null) {
			out.println("[");
			++indentLevel;
			for (Option e : aModelAccess.getOptions()) {
				printIndent();
				e.visit(this);
			}
			--indentLevel;
			printIndent();
			out.println("]");
		} else {
			out.println("null");
		}
		--indentLevel;printIndent();
		out.println(")");
	}
	
	public void visitBox(Box aBox) {
		out.print("Box(");
		++indentLevel;out.println();
		printIndent();
		out.print("type=");
		if (aBox.getType() != null) {
			aBox.getType().visit(this);
		} else {
			out.println("null");
		}
		printIndent();
		out.print("options=");
		if (aBox.getOptions() != null) {
			out.println("[");
			++indentLevel;
			for (Option e : aBox.getOptions()) {
				printIndent();
				e.visit(this);
			}
			--indentLevel;
			printIndent();
			out.println("]");
		} else {
			out.println("null");
		}
		printIndent();
		out.print("children=");
		if (aBox.getChildren() != null) {
			out.println("[");
			++indentLevel;
			for (BoxSpec e : aBox.getChildren()) {
				printIndent();
				e.visit(this);
			}
			--indentLevel;
			printIndent();
			out.println("]");
		} else {
			out.println("null");
		}
		--indentLevel;printIndent();
		out.println(")");
	}
	
	public void visitCommand(Command aCommand) {
		out.print("Command(");
		++indentLevel;out.println();
		printIndent();
		out.print("name=");
		if (aCommand.getName() != null) {
			aCommand.getName().visit(this);
		} else {
			out.println("null");
		}
		printIndent();
		out.print("expr=");
		if (aCommand.getExpr() != null) {
			aCommand.getExpr().visit(this);
		} else {
			out.println("null");
		}
		printIndent();
		out.print("arguments=");
		if (aCommand.getArguments() != null) {
			out.println("[");
			++indentLevel;
			for (BoxSpec e : aCommand.getArguments()) {
				printIndent();
				e.visit(this);
			}
			--indentLevel;
			printIndent();
			out.println("]");
		} else {
			out.println("null");
		}
		--indentLevel;printIndent();
		out.println(")");
	}
	
	public void visitOption(Option aOption) {
		out.print("Option(");
		++indentLevel;out.println();
		printIndent();
		out.print("name=");
		if (aOption.getName() != null) {
			aOption.getName().visit(this);
		} else {
			out.println("null");
		}
		printIndent();
		out.print("value=");
		if (aOption.getValue() != null) {
			aOption.getValue().visit(this);
		} else {
			out.println("null");
		}
		--indentLevel;printIndent();
		out.println(")");
	}
	
	public void visitIntegerValue(IntegerValue aIntegerValue) {
		out.print("IntegerValue(");
		out.print("value=");
		if (aIntegerValue.getValue() != null) {
			out.print(aIntegerValue.getValue());
		} else {
			out.print("null");
		}
		out.println(")");
	}
	
	public void visitIdentValue(IdentValue aIdentValue) {
		out.print("IdentValue(");
		out.print("value=");
		if (aIdentValue.getValue() != null) {
			out.print(aIdentValue.getValue());
		} else {
			out.print("null");
		}
		out.println(")");
	}
	
	public void visitStringValue(StringValue aStringValue) {
		out.print("StringValue(");
		out.print("value=");
		if (aStringValue.getValue() != null) {
			out.print(aStringValue.getValue());
		} else {
			out.print("null");
		}
		out.println(")");
	}
	
	public void visitListValue(ListValue aListValue) {
		out.print("ListValue(");
		++indentLevel;out.println();
		printIndent();
		out.print("elements=");
		if (aListValue.getElements() != null) {
			out.println("[");
			++indentLevel;
			for (Ident e : aListValue.getElements()) {
				printIndent();
				e.visit(this);
			}
			--indentLevel;
			printIndent();
			out.println("]");
		} else {
			out.println("null");
		}
		--indentLevel;printIndent();
		out.println(")");
	}
	
	public void visitName(Name aName) {
		out.print("Name(");
		++indentLevel;out.println();
		printIndent();
		out.print("elements=");
		if (aName.getElements() != null) {
			out.println("[");
			++indentLevel;
			for (Ident e : aName.getElements()) {
				printIndent();
				e.visit(this);
			}
			--indentLevel;
			printIndent();
			out.println("]");
		} else {
			out.println("null");
		}
		--indentLevel;printIndent();
		out.println(")");
	}
	
	public void visitFunction(Function aFunction) {
		out.print("Function(");
		++indentLevel;out.println();
		printIndent();
		out.print("name=");
		if (aFunction.getName() != null) {
			aFunction.getName().visit(this);
		} else {
			out.println("null");
		}
		printIndent();
		out.print("arguments=");
		if (aFunction.getArguments() != null) {
			out.println("[");
			++indentLevel;
			for (Expression e : aFunction.getArguments()) {
				printIndent();
				e.visit(this);
			}
			--indentLevel;
			printIndent();
			out.println("]");
		} else {
			out.println("null");
		}
		--indentLevel;printIndent();
		out.println(")");
	}
	
	public void visitIntegerExpression(IntegerExpression aIntegerExpression) {
		out.print("IntegerExpression(");
		out.print("value=");
		if (aIntegerExpression.getValue() != null) {
			out.print(aIntegerExpression.getValue());
		} else {
			out.print("null");
		}
		out.println(")");
	}
	
	public void visitStringExpression(StringExpression aStringExpression) {
		out.print("StringExpression(");
		out.print("value=");
		if (aStringExpression.getValue() != null) {
			out.print(aStringExpression.getValue());
		} else {
			out.print("null");
		}
		out.println(")");
	}
	
	public void visitIdent(Ident aIdent) {
		out.print("Ident(");
		out.print("value=");
		if (aIdent.getValue() != null) {
			out.print(aIdent.getValue());
		} else {
			out.print("null");
		}
		out.println(")");
	}
	
	private void printIndent() {
		for (int i = 0; i < indentLevel; ++i) {
			out.print("  ");
		}
	}
}
